<?php

namespace app\ports\controller;

use app\ports\constants\BonusConstants;
use think\Config;
use think\Db;

/**
 * 分红
 */
class Bonus
{

	use \app\common\traits\ToolTrait;

	/**
	 * - 逻辑
	 *	- A (虚拟主账号)、B|C|D（次级账号=>Z））
	 *		- A 的达标计算 
	 *			- 平台交易 >= 晋升等级模板限制交易 = 晋升
	 *		- B（达标） => 自动生成（克隆）与 B 关联的 B1|B2|B3|B4（X） 同级账号(C|D同上)（注：公众号可做登录）
	 *		- 收益
	 *			
	 *			- 交易额 30000 万 * (P1|P2|P3)分红比率如(万分之0.5) = 总分红金额(1.5万)
	 *			- 实际 3 (B|C|D)个达标 分红金额/个 (0.5万) = 总分红金额(1.5万) / 实际 3个
	 *			- 平均值 0.5 -> [Z * 3 = 1.5] + [X * 12 = 6] + [A * 1 = 0.5 ] = 8
	 *			- 进账分
	 *				- Z - 1.5 
	 * 				- X - 6.5
	 */

	/**
	 * 计算入口
	 */
	public function earns_calc()
	{
		try {
			$now_days = date("d");
			if ($now_days >= 15 && $now_days <= 20) {
				// $times = date("Y-m", time());
				// 默认计算
				$times = date("Y-m", strtotime("-1 month", time()));
				$reqCheck = $this->check_month_calc($times);
				if ($reqCheck) {
					$template = \app\ports\controller\publics\Template::instance()->bonus_calc();
					if ($template) {
						foreach ($template as $vals) {
							$this->_procc_cash($vals, $times);
						}
						$this->update_calc_state($reqCheck);
					}
				} else {
					throw new \Exception($times . "已计算完成");
				}
			} else {
				throw new \Exception("未到计算时间");
			}
		} catch (\Exception $e) {
			// $this->logs("./portsLogs/bonus", "bonus_calc_" . date("Y-m") . ".txt", [$e->getMessage()]);
			echo $e->getMessage();
		}
	}

	/**
	 * 
	 */
	protected function update_calc_state($id)
	{
		$table = "bonus_cash_switch";
		$update = ["state" => 2];
		Db::name($table)->where("id = " . $id)->update($update);
	}

	/**
	 * @return boolean
	 */
	protected function check_month_calc($times)
	{
		if ($times) {
			$table = "bonus_cash_switch";
			$where = "times = " . strtotime($times);
			$find = Db::name($table)
				->where($where)
				->field("id,state")
				->find();
			if (!$find) {
				$data = ["times" => strtotime($times), "state" => 1, "create_time" => time()];
				$req_store = Db::name($table)->insertGetId($data);
				if ($req_store) {
					return $req_store;
				}
			} else {
				if ($find["state"] == 1) {
					return $find["id"];
				}
			}
		}
		return false;
	}

	/**
	 * 按等级获取达标代理
	 * 获取交易（MAX3.0、MAX5.0 总和）
	 * 按等级编号获取 返现模板（分红模板）
	 * 
	 */

	protected function _procc_cash($option = [], $times = "")
	{
		if (!empty($option)) {
			$sum = $this->_trans_total($option["lev_code"], $times);
			if ($sum) {
				// 分红金额
				// $divAmt = bcmul((string)$sum, bcdiv((string)$option["radio"], '10000', 6), 2);
				$divAmt = $this->_calc_trans_bonus_money($sum, $option["radio"]);
				$option["trans"] = $sum;
				$option["money"] = $divAmt;
				$option["times"] = $times;
				$this->_calc($option);
			}
		}
	}

	/**
	 * 分红金额计算
	 */
	protected function _calc_trans_bonus_money($sums, $radio)
	{
		return bcmul(bcmul((string)$sums, (string)BonusConstants::CALC_BONUS_MULTI), bcdiv((string)$radio, '10000', 6), 2);
	}

	/**
	 * 分红计算
	 * @param array $option
	 */
	protected function _calc($option)
	{
		// 真实达标人数
		$nums = $this->_stands_person_nums($option["lev_code"], $option["times"]);
		if ($nums) {
			$cash_money = bcdiv((string)$option["money"], (string) $nums, 2);
			if ($cash_money) {
				$option["per_nums"] = $nums;
				$option["avg_earns"] = $cash_money;
			}
		} else {
			$option["per_nums"] = 0;
			$option["avg_earns"] = $option["money"];
		}
		$this->_store($option);
	}

	/**
	 * 存储
	 * @param array $option
	 */
	protected function _store($option)
	{
		/**
		 * 存储 分红明细记录
		 * 存储 分红余额更新记录
		 * 存储 分红余额
		 */
		$upgrade = $this->_upgrade_array($option["lev_code"], $option["times"]);
		if ($upgrade) {
			foreach ($upgrade as $key => $val) {
				$temp = [];
				$temp["lev_code"]	= $val["lev_code"];
				$temp["agid"]	= $val["agid"];
				$temp["isReals"] = $val["isReals"];
				$temp["times"]	= strtotime($option["times"]);
				$conn = Db::connect("db." . $val["versions"]);
				if ($conn) {
					$check = $conn->name("bonus_details")->where($temp)->count();
					if (!$check) {
						$temp["trans"]	= $option["trans"];
						$temp["radio"]  = $option["radio"];
						$temp["money"]  = $option["money"];
						$temp["per_nums"]	= $option["per_nums"];
						$temp["earns"]	= $option["avg_earns"];
						$temp["create_time"] = time();
						$id = $conn->name("bonus_details")->insert($temp);
						if ($id) {
							$this->store_balance($conn, $temp);
						}
					}
				}
			}
		}
	}

	/**
	 * 存储余额
	 */
	protected function store_balance($db_conn, $option)
	{
		if (!empty($option)) {
			$table = "";
			if ($option["isReals"] == 1) $table = "balance";
			if ($option["isReals"] == 2) $table = "balance_virtual";
			$cordsData = [];
			$cordsData["main_type"] = 2;
			$cordsData["main_id"] = $option["agid"];
			$cordsData["company_id"] = $this->_company_id($db_conn, $cordsData["main_id"]);
			$cordsData["balance_type_id"] = $this->balance_type($db_conn);
			$cordsData["before"] = $this->_balanec($db_conn, $table, $cordsData["main_id"]);
			$cordsData["changes"] = $option["earns"];
			$cordsData["after"] = bcadd((string)$cordsData["before"], (string) $cordsData["changes"], 2);
			$cordsData["bonus_times"] = $option["times"];
			$cordsData["isReals"] = $option["isReals"];
			$cordsData["create_time"] = time();
			$cordsData["mome"] = $option["lev_code"] . "分红收益";
			$id = $db_conn->name("bonus_balance_change_cords")->insert($cordsData);
			if ($id) {
				$this->update_balance($db_conn, $table, $cordsData["main_id"], $cordsData["changes"]);
			}
		}
	}

	/**
	 * 更新余额 - 真
	 * 
	 */
	protected function update_balance($db_conn, $table, $agid, $money)
	{
		if ($table) {
			$check = $db_conn->name($table)
				->where("main_id = " . $agid)
				->count();
			if ($check) {
				$update = [
					"money" => Db::raw("money" . " + " . $money),
					"total" => Db::raw("total" . " + " . $money)
				];
				$db_conn->name($table)->where("main_id = " . $agid)->update($update);
			} else {
				$data = [
					"main_type" => 2,
					"main_id"	=> $agid,
					"money"		=> $money,
					"total"		=> $money
				];
				$db_conn->name($table)->insert($data);
			}
		}
	}

	/**
	 * 获取当前余额 - 真
	 */
	protected function _balanec($db_conn, $table, $agid)
	{
		$bal = '0.00';
		if ($table) {
			$res = $db_conn->name($table)->where("main_id = " . $agid)->value("money");
			if ($res) $bal = $res;
		}
		return $bal;
	}

	/**
	 * 余额类型
	 */
	protected function balance_type($db_conn)
	{
		$type = 0;
		$res = $db_conn->name("balance_type")->where("name = '分红收益'")->value("id");
		if ($res) $type = $res;
		return $type;
	}

	/**
	 * 公司ID
	 */
	protected function _company_id($db_conn, $agid)
	{
		$id = 0;
		$res  = $db_conn->name("user")->where("id = {$agid}")->value("company_id");
		if ($res) $id = $res;
		return $id;
	}

	/**
	 * 达标-列表
	 * @param $lev_id
	 * @param string $times
	 * @return array|bool
	 */
	protected function _upgrade_array($lev_code, $times)
	{

		if (!empty($lev_code) && !empty($times)) {
			$arrs = [];
			$db_config_arr = Config::get("db");
			if ($db_config_arr) {
				foreach ($db_config_arr  as $k => $v) {
					$query = Db::connect($v)->name("bonus_upgrade")
						->field("agid,lev_code,isReals,'" . $k . "' versions")
						->where("lev_code = '{$lev_code}' and times = " . strtotime($times))
						->select();
					if ($query) {
						$arrs = array_merge($arrs, $query);
					}
				}
			}
			return $arrs;
		}
		return false;
	}

	/**
	 * 达标人数
	 * @param string $lev_code
	 * @param string $times
	 * @return int
	 */
	protected function _stands_person_nums($lev_code = "", $times = "")
	{
		$nums = 0;
		if (!empty($lev_code) && !empty($times)) {
			$db_config_arr = Config::get("db");
			if ($db_config_arr) {
				foreach ($db_config_arr  as $k => $v) {
					$count = Db::connect($v)->name("bonus_upgrade")
						->where("lev_code = '{$lev_code}' and isReals in(1,2) and times = " . strtotime($times))
						->count();
					$nums += $count;
				}
			}
		}
		return $nums;
	}

	/**
	 * 交易总和
	 * @param string $pro_ids 计算产品ID
	 * @param string $times
	 * @return float
	 */
	protected function _trans_total($lev_code, $tims)
	{
		$sum = 0;
		if (!empty($lev_code) && !empty($tims)) {
			$table = "bonus_calc_trans_" . date("Y", strtotime($tims));
			$db_config_arr = Config::get("db");
			if ($db_config_arr) {
				foreach ($db_config_arr as $v) {
					$conn = Db::connect($v);
					$isExist = $conn->query("SHOW TABLES like '" . $v["prefix"] . $table . "'");
					if ($isExist) {
						if ($conn) {
							$pro_ids = $this->_cash_pro_ids($conn, $lev_code);
							if ($pro_ids) {
								$total = $conn->name($table)->whereIn("proid", $pro_ids)->where("times = " . strtotime($tims))->sum("transAmt");
								$sum += $total;
							}
						}
					}
				}
			}
		}
		return $sum;
	}

	/**
	 * 获取产品ID
	 * @return string|bool
	 */
	protected function _cash_pro_ids($conn, $lev_code)
	{
		if (!empty($conn) && !empty($lev_code)) {
			$lev_id = $conn->name("bonus_level")
				->where("code = '{$lev_code}' and state = 1")
				->value("id");
			if ($lev_id) {
				$pro_ids = $conn->name("bonus_cash")->where("lev_id = " . $lev_id . " and state = 1")->value("pro_ids");
				if ($pro_ids) return $pro_ids;
			}
		}
		return false;
	}
}
